// Copyright (c) 2022-2024 0x5BFA
// Licensed under the MIT License. See the LICENSE.

using Microsoft.UI.Xaml.Data;

#nullable enable

namespace FluentHub.App.Converters
{
	public abstract class ValueConverter<TSource, TTarget> : IValueConverter
	{
		public TTarget? Convert(TSource? value)
		{
			return Convert(value, null, null);
		}

		public TSource? ConvertBack(TTarget? value)
		{
			return ConvertBack(value, null, null);
		}

		public object? Convert(object? value, Type? targetType, object? parameter, string? language)
		{
			// CastExceptions will occur when invalid value, or target type provided.
			return Convert((TSource?)value, parameter, language);
		}

		public object? ConvertBack(object? value, Type? targetType, object? parameter, string? language)
		{
			// CastExceptions will occur when invalid value, or target type provided.
			return ConvertBack((TTarget?)value, parameter, language);
		}

		protected virtual TTarget? Convert(TSource? value, object? parameter, string? language)
		{
			throw new NotSupportedException();
		}

		protected virtual TSource? ConvertBack(TTarget? value, object? parameter, string? language)
		{
			throw new NotSupportedException();
		}
	}

	public abstract class ToObjectConverter<T> : ValueConverter<T?, object?>
	{
		protected override object? Convert(T? value, object? parameter, string? language)
		{
			return value;
		}

		protected override T? ConvertBack(object? value, object? parameter, string? language)
		{
			return (T?)value;
		}
	}

	public class InverseBooleanConverter : ValueConverter<bool, bool>
	{
		protected override bool Convert(bool value, object? parameter, string? language)
		{
			return !value;
		}

		protected override bool ConvertBack(bool value, object? parameter, string? language)
		{
			return !value;
		}
	}

	public class NullToTrueConverter : ValueConverter<object?, bool>
	{
		public bool Inverse { get; set; }

		protected override bool Convert(object? value, object? parameter, string? language)
		{
			return Inverse ? value != null : value == null;
		}

		protected override object? ConvertBack(bool value, object? parameter, string? language)
		{
			return null;
		}
	}

	public class StringNullOrWhiteSpaceToTrueConverter : ValueConverter<string, bool>
	{
		public bool Inverse { get; set; }

		protected override bool Convert(string? value, object? parameter, string? language)
		{
			return Inverse ? !string.IsNullOrWhiteSpace(value) : string.IsNullOrWhiteSpace(value);
		}

		protected override string ConvertBack(bool value, object? parameter, string? language)
		{
			return string.Empty;
		}
	}
}
